﻿#SingleInstance, Force
#NoTrayIcon
#NoEnv
SendMode Input
SetBatchLines, -1
DetectHiddenWindows On
SetWorkingDir %A_ScriptDir%  
#Include %A_ScriptDir%\lib\class_json.ahk
#Include %A_ScriptDir%\lib\ZipFile.ahk
;~ #Include %A_ScriptDir%\lib\Functions.ahk
#Include %A_ScriptDir%\lib\UUIDCreate.ahk
#Include %A_ScriptDir%\lib\GetExtIcon.ahk
#Include %A_ScriptDir%\lib\Path_API.ahk
#Include %A_ScriptDir%\lib\Class_QZGlobal.ahk
#Include %A_ScriptDir%\lib\QZ_API.ahk
#Include %A_ScriptDir%\lib\QZ_Engine.ahk
Menu, Tray, Icon, %A_ScriptDir%\User\Icons\default.icl
IniRead, hGUI, %A_TEMP%\MZC, Auto, GUI
if WinExist("ahk_id " hGUI)
{
    MsgBox, 36, %cons_Title_QZA%, 当前QuickZ配置界面正在运行，是否强制关闭？
    ifMsgbox No
        return
    WinClose, ahk_id %hGUI%
}

Global gQZConfig, gQZShell, QZGlobal
gQZConfig := QZ_ReadConfig(QZGlobal.Config)  ;调用Ahk文件：QZ_ReadConfig.ahk，作用：读取配置文件

QZAFile = %1%

if FileExist(QZAFile)
    GoSub, QZImport
else
    GoSub, QZExport
return

; =============================================
; 加载导入界面
; =============================================
QZImport:

cons_Setting := "【设置】"
cons_SettingIcon := "%A_ScriptDir%\Icons\default.icl:25"
cons_Filters := "【过滤器】"
cons_FiltersIcon := "%windir%\system32\shell32.dll:54"
cons_menuz := "【菜单项目】"
cons_menuzIcon := "%windir%\system32\shell32.dll:43"
cons_vimd := "【VIMD】"
cons_vimdIcon := "%windir%\system32\shell32.dll:1"
cons_gesture := "【鼠标手势】"
cons_gestureIcon := "%windir%\system32\shell32.dll:54"
cons_Separator := "--------------"


cons_HelpImport =
(

)
;2、设置导入的变量
Global gQZImportConfig,IsJSON,QZAFileTemp
If RegExMatch(QZAFile, "i)\.json$")
{
    gQZImportConfig := QZ_ReadConfig(QZAFile)
    IsJSON:=1
}
If RegExMatch(QZAFile, "i)\.qza$")
{
    IsJSON:=0
    SplitPath, QZAFile, OutFileName, , , OutNameNoExt
    QZAFileTemp := A_Temp "\QZA_" OutNameNoExt
    QZAFileJson :=  QZAFileTemp "\qza.json"
    QZAFileZip := A_Temp "\" OutNameNoExt ".zip"
    FileCopy, %QZAFile%, %QZAFileZip%, 1
    If Fileexist(QZAFileTemp)
        FileRemoveDir, %QZAFileTemp%, 1
    FileCreateDir, %QZAFileTemp%
    ObjZip := ZipFile(QZAFileZip)
    ObjZip.unpack("*.*", QZAFileTemp)
    gQZImportConfig := QZ_ReadConfig(QZAFileJson)
    FileDelete, %QZAFileZip%
    FileDelete, %QZAFileJson%
}
iName := gQZImportConfig.QuickZApp.Name
iAuthor := gQZImportConfig.QuickZApp.Author
iInfo := gQZImportConfig.QuickZApp.info


;3、设置菜单项配置涉及用户变量

global QZImport_ObjSetting := {}       ;设置 数组
global QZImport_ObjTop := {}           ;窗体树 数组
global QZImport_ObjFilters := {}            ;过滤器 数组
global QZImport_ObjMenuZ := {}         ;菜单项 数组
global QZImport_Objvimd := {}          ;vimd 数组
global QZImport_Objgesture:={}         ;gesture 数组
global QZImport_ObjFile:={}            ;文件 数组
;~ QZImport_ObjUserVar := {}       ;JOSN MenuZ

if QZImport_ImgItem
    IL_Destroy(QZImport_ImgItem)
else
    QZImport_ImgItem := IL_Create(1,10,0)

if QZImport_ImgFile
    IL_Destroy(QZImport_ImgFile)
else
    QZImport_ImgFile := IL_Create(1,10,0)

QZImport_ImgItem_Icons := {}
QZImport_ImgFile_Icons := {}

GetExtIcon("Folder", iFile, iNum)
IL_Add(QZImport_ImgFile, ifile, iNum)

Gui, QZImport: Destroy
Gui, QZImport: Default
Gui, QZImport: +theme -DPIScale +hwndhQZImport
Gui, QZImport: Font, s9, Microsoft YaHei
GUI, QZImport: Add, Tab2, x5 y5 w400 h500 ,说明|菜单|文件|导入
GUI, QZImport: Add, Text, x15 y40 w380 , 名称：%iName%
GUI, QZImport: Add, Text, x15 y75 w380 , 作者：%iAuthor%
GUI, QZImport: Add, Edit, x15 y110 w380 h340 Readonly, 说明：%iInfo%
GUI, QZImport: Tab, 2
Gui, QZImport: Add, TreeView, Checked x15 y40 w380 h455 +hwndhQZImportItem AltSubmit ImageList%QZImport_ImgItem% -Lines 0x1000 gQZImport_TVEvent_Item
GUI, QZImport: Tab, 3
Gui, QZImport: Add, TreeView, Checked x15 y40 w380 h410 +hwndhQZImportFile AltSubmit ImageList%QZImport_ImgFile% gQZImport_TVEvent_File
GUI, QZImport: Tab, 4
;GUI, QZImport: Add, ListView, x15 y40 w380 h455 Grid, 变量名|内容
;GUI, QZImport: Tab, 5
;GUI, QZImport: Add, Edit, x15 y40 w380 h415 Readonly, % cons_HelpImport
gui,QZImport:Add,Checkbox, x30 y80 checked ,导入的菜单使用红色标注
;~ GUI, QZImport: Add, Button, x65 y460 w120 gQZImport_Json, 导入JSON
GUI, QZImport: Add, Button, x195 y460 w120 gQZImport_QZA,  导入QZA文件
GUI, QZImport: Add, Button, x325 y460 w70 gQZImportGUIClose, 关闭
SetExplorerTheme(hQZImportItem)
SetExplorerTheme(hQZImportFile)
Gui, QZImport: Show, w410 h510, QZA 导入
ControlSend, Edit1, {end}, ahk_id %hQZImport%
Gui, QZImport: TreeView, SysTreeView321
QZImport_LoadSetting()
QZImport_LoadMenuZ(cons_menuz, cons_menuzIcon, "menuz")
QZImport_LoadFilters()
QZImport_LoadVIMD(cons_vimd, cons_vimdIcon, "vimd")
;~ QZImport_Load(cons_gesture, cons_gestureIcon, "gesture")
Gui, QZImport: TreeView, SysTreeView322
if (IsJSON=0)
    QZImport_Files(QZAFileTemp)
return

QZImportGUIClose:
    ExitApp
return

QZImport_QZA:
  QZImport_Do(IsJSON)
return

QZImport_Json:
  QZImport_Do(IsJSON)
return

QZImport_TVEvent_Item:
    Gui, QZImport: default
    Gui, QZImport: TreeView, SysTreeView321
    If A_GuiEvent = Normal
        GoSub, QZImport_TVEvent
return

QZImport_TVEvent_File:
    Gui, QZImport: default
    Gui, QZImport: TreeView, SysTreeView322
    If A_GuiEvent = Normal
        GoSub, QZImport_TVEvent
return


QZImport_TVEvent:
    TV_Modify(A_EventInfo, "select")
    if TV_Get(A_EventInfo, "Check")
    {
        QZImport_CheckSetting(A_EventInfo, "check")
        QZImport_CheckParent(A_EventInfo, "Check")
        QZImport_CheckChild(A_EventInfo, "Check")
    }
    else
    {
        QZImport_CheckSetting(A_EventInfo, "-check")
        QZImport_CheckChild(A_EventInfo, "-Check")
    }
return
; 加载父项
QZImport_CheckParent(aID, opt)
{
    global QZImport_ObjMenuZ, QZImport_ObjFilters
    if (Parentid := TV_GetParent(aID))
    {
        TV_Modify(ParentID, opt)
        QZImport_CheckParent(ParentID, opt)
        QZImport_CheckSetting(ParentID, opt)
    }
}
; 加载子项
QZImport_CheckChild(aID, opt)
{
    global QZImport_ObjMenuZ, QZImport_ObjFilters
    if ( ChildID := TV_GetChild(aID) )
    {
        Loop
        {
            if ChildID
            {
                if ( SubChildID := TV_GetChild(ChildID) )
                    QZImport_CheckChild(ChildID, opt)
                TV_Modify(ChildID, opt)
                QZImport_CheckSetting(ChildID, opt)
            }
            else
            {
                break
            }
            ChildID := TV_GetNext(ChildID)
        }
    }
}

QZImport_LoadSetting()      ;加载 Json下的setting
{
    global cons_Setting, cons_SettingIcon, QZImport_ObjTop, QZImport_ObjSetting, gQZImportConfig
    opt := QZImport_TVOptions({icon:cons_SettingIcon})
    ParentID := TV_Add(cons_Setting, 0, "Expand check " opt)
    QZImport_ObjTop[ParentID] := "setting"
    ;~ for name, var in gQZImportConfig.setting
        ;~ QZImport_ObjSetting[TV_Add(name, ParentID, opt)] := {name:name, option:true} 
    for name, var in gQZImportConfig.setting
    {
        if (name!="userenv")
            QZImport_ObjSetting[TV_Add(name, ParentID," check " opt)] := {name:name, option:true}  
        else
        {
            UserPID:=TV_Add(name, ParentID, " check " opt)
            QZImport_ObjSetting[UserPID] :=  {name:"userenv", option:true}  
            UserEnvArray:=gQZImportConfig.setting.userenv
            Loop % UserEnvArray.MaxIndex()
            {
                ItemEnv:=UserEnvArray[A_Index]
                EnvName:=itemenv.name . "    ||    " . itemenv.value
                QZImport_ObjSetting[TV_Add(EnvName, UserPID, " check " opt)] := {name:EnvName, option:true} 
            }
        }
    }
}

QZImport_LoadFilters()  ;加载 Json下的filter
{
    global cons_Filters, cons_FiltersIcon, QZImport_ObjTop, QZImport_ObjFilters, gQZImportConfig
    opt := QZImport_TVOptions({icon:cons_FiltersIcon})
    ParentID:= TV_Add(cons_Filters, 0, "Expand check " opt)
    QZImport_ObjTop[ParentID] := "Filters"
    for name, var in gQZImportConfig.Filters
    {
        ;~ name := var.name
        ShowName:=var.name
        QZImport_ObjFilters[TV_Add(ShowName, ParentID,"check " opt)] := {name:name, option:false}
    }
}

QZImport_LoadMenuZ(aName, aICON, aObjName)   ;加载 Json下的menuz
{
    global QZImport_ObjTop, gQZImportConfig
    aObj := gQZImportConfig[aObjName]
    opt := QZImport_TVOptions({icon:aICON})
    SubID := TV_Add(aName, 0, opt " expand check ")
    QZImport_ObjTop[SubID] := aObjName
    QZImport_LoadMenuZSub(aObj, SubID,aLevel:=2)
}

QZImport_LoadMenuZSub(aObjSub, aID,aLevel)       ;加载 Json下的menuz的子项
{
    global  cons_Separator,  QZImport_ObjMenuZ,gQZImportConfig
    Loop % aObjSub.MaxIndex()
    {
        Item := aObjSub[A_Index]
        ItemUUID:=Item.uuid
        name := Item.name
        Showname := gQZImportConfig.Items[ItemUUID].name
        opt := QZImport_TVOptions(item.options)
        if not strlen(item.uuid) ;and aLevel > 2
            TV_Add(cons_Separator, aID, " check " opt)
        else
        {
           SubID := TV_Add(Showname, aID, " check " opt)
            QZImport_ObjMenuZ[SubID] := Item
        }
        if IsObject(Item.SubItem)
          QZImport_LoadMenuZSub(Item.SubItem, SubID,aLevel+1)
    }
}

QZImport_LoadVIMD(aName, aICON, aObjName)   ;加载 Json下的VIMD
{
    global QZImport_ObjTop, gQZImportConfig
    aObj := gQZImportConfig[aObjName]
    opt := QZImport_TVOptions({icon:aICON})
    SubID := TV_Add(aName, 0, opt " expand check ")
    QZImport_ObjTop[SubID] := aObjName
    QZImport_LoadVIMDSub(aObj, SubID,aLevel:=2)
}

QZImport_LoadVIMDSub(aObjSub, aID,aLevel)       ;加载 Json下的VIMD的子项
{
    global  QZImport_Objvimd,gQZImportConfig
    Loop % aObjSub.MaxIndex()
    {
        Item := aObjSub[A_Index]
        name := Item.name
        ;~ opt := QZExport_TVOptions(item.options)
        ParentID := TV_Add(name, aID, " check ")
        QZImport_Objvimd[ParentID] := Item
        ;~ loop % Item.Modes.maxindex()
        ;~ {
            ;~ Mode:=Item.Modes[A_index]
            ;~ ModeName:=mode.Name            
            ;~ SubID := TV_Add(ModeName, ParentID)
        ;~ }
    }
}

QZImport_TVOptions(aIcon)       ;返回菜单项对应的图标
{
    global QZImport_ImgItem, QZImport_ImgItem_Icons
    Opt := "" ;默认返回的TV控件的选项为空
    ; == 开始判断 TreeView 的图标选项 ==========
    ;~ icon := aIcon.iconfile
    icon := aIcon.iconfile      ;Kawvin修改
    if strlen(icon) ; icon 有效
    {
        if ic := QZImport_ImgItem_Icons[icon] ; 如果保存对象的QZImport_ImgItem_Icons中有对应的列表，则直接设置，无需判断
            opt_icon := "icon" ic
        else if RegExMatch(icon, ":[-\d]*$") ; example.exe:1 的格式
        {
            pos := RegExMatch(icon, ":[^:]*$")
		    file   := QZ_ReplaceEnv(SubStr(icon, 1, pos-1))
            Number := (number := substr(icon, pos+1)) > 0 ? Number + 1 : Number
            ic := IL_Add(QZImport_ImgItem, file, Number)
            if ic
            {
                Opt_icon := "icon" ic 
                QZImport_ImgItem_Icons[icon] := ic ; 保存到 QZImport_ImgItem_Icons 中，避免重复加载
            }
      }
	  else
      {
            file := QZ_ReplaceEnv(icon)   ; menuz.ico 的格式
            ic := IL_Add(QZImport_ImgItem, file)
            if ic
            {
                Opt_icon := "icon" ic 
                QZImport_ImgItem_Icons[icon] := ic ; 保存到 QZImport_ImgItem_Icons 中，避免重复加载
            }
      }
    }
    else
        opt_icon := "icon9999" 
    if not ic ; 如果无icon，必须设置为最大值，让图标为空
        opt_icon := "icon9999" 
    return opt_icon
    ; == 结束判断 TreeView 的图标选项 ==========
}

QZImport_Files(aPath, aID=0)        ;加载导出文件
{
    global QZImport_ObjFile
    SplitPath, aPath, filename
    ParentID := TV_Add(filename, aID, "icon" QZIm_GetIcon(aPath) " check ")
    QZImport_ObjFile[ParentID] := aPath
    Loop, %aPath%\*.*, 1
    {
        SplitPath, A_loopfilename, , , ext
        If (FileExist(A_loopfilefullpath), "D")
        {
            QZImport_Files(A_loopfilefullpath, ParentID)
        }
        else
        {
            PathID := TV_Add(A_loopfilename, ParentID, "icon" QZIm_GetIcon(A_loopfilename) " check")
            QZImport_ObjFile[PathID] := A_loopfilefullpath
        }
    }
}

QZIm_GetIcon(aPath)     ;获取导出文件对应图标
{
    global QZImport_ImgFile, QZImport_ImgFile_Icons
    if Instr(Fileexist(aPath),"D")
        return 1
    SplitPath, aPath, , , ext
    if QZImport_ImgFile_Icons[ext]
    {
        idx := QZImport_ImgFile_Icon[ext]
    }
    else
    {
        GetExtIcon("." ext, iFile, iNum)
        if instr(inum, "-")
            idx := IL_Add(QZImport_ImgFile, ifile, inum)
        else
            idx := IL_Add(QZImport_ImgFile, ifile, inum+1)
        QZImport_ImgFile_Icon[ext] := idx
    }
    return idx
}

QZImport_CheckSetting(aID, aOpt)
{
    global QZImport_ObjSetting, QZImport_ObjTop
    if (QZImport_ObjTop[TV_GetParent(aID)] = "setting")
    {
        if InStr(aOpt, "-")
            QZImport_ObjSetting[aID].option := False
        else
            QZImport_ObjSetting[aID].option := True
    }
}

QZImport_Do(aJson=false)
{
   Global QZAFileTemp
    global QZImport_ObjMenuZ, QZImport_ObjFilters, QZImport_ObjTop, QZImport_ObjFile, QZImport_ObjSetting,QZImport_Objvimd, gQZImportConfig,gQZConfig,QZGlobal    ;,QZImport_ObjUserVar
    Gui, QZImport: Default
    GuiControlGet, NewItemIsRed,   , Button1      ;获取值是否新菜单显示红色
    ;~ msgbox % NewItemIsRed
    ;~ return
    Gui, QZImport: TreeView, SysTreeView321
    ItemID = 0  ; 这样使得首次循环从树的顶部开始搜索.
    Loop
    {
        ItemID := TV_GetNext(ItemID)
        if TV_Get(ItemID, "Check")
        {
            if (QZImport_ObjTop[ItemID] = "setting" )       ;导入setting
            {
                ChildID := TV_GetChild(ItemID)
                Loop
                {
                    if not ChildID ; 没有更多项目了.
                        break
                    if TV_Get(ChildID, "Check")
                    {
                        set := QZImport_ObjSetting[ChildID].name
                        ;~ msgbox % set
                        if (set="gesture") or (set="global") or (set="menuz") or (set="vimd")
                            gQZConfig.setting[set] := gQZImportConfig.Setting[set]
                        else if  (set="userenv") {
                            QZImport_UserENV(ChildID)
                        } else {
                            
                        }
                    }
                    ChildID := TV_GetNext(ChildID)
                }
            }
            else if (QZImport_ObjTop[ItemID] = "menuz" )
            {
                ;~ menuzArray:=[]
                ;~ menuzArray:=gQZConfig["menuz"] 
                ;~ QZImport_DoSub(ItemID,menuzArray)
                ;~ gQZConfig["menuz"] := menuzArray
                TemmenuzArray:=[]
                TemmenuzArray:=QZImport_DoSub(ItemID,NewItemIsRed)
                Loop % TemmenuzArray.MaxIndex()
                {
                    if gQZConfig.menuz.MaxIndex()
                        gQZConfig.menuz[gQZConfig.menuz.MaxIndex()+1] := TemmenuzArray[A_Index]
                    else
                        gQZConfig.menuz[1] := TemmenuzArray[A_Index]
                }
            }
            else if (QZImport_ObjTop[ItemID] = "Filters" )
            {
                ChildID := TV_GetChild(ItemID)
                Loop
                {
                    if not ChildID ; 没有更多项目了.
                        break
                    if TV_Get(ChildID, "Check")
                    {
                        ;~ filter := QZImport_ObjFilters[ChildID].name
                        ;~ gQZConfig.Filters[filter] := gQZImportConfig.Filters[filter]
                        
                        filter := QZImport_ObjFilters[ChildID].name
                        if gQZImportConfig.Filters[filter].NewID
                        {   
                            ChildID := TV_GetNext(ChildID)
                            continue
                        }
                        FilterUUID:=UUIDCreate(1, "U")      ;生成新的FilterUUID
                        for k,v in gQZConfig.filters
                        {
                            if v.name=gQZImportConfig.Filters[filter].Name
                            {
                                gQZImportConfig.Filters[filter].name.= "-副本"
                                break
                            }
                        }
                        gQZConfig.Filters[FilterUUID]:=gQZImportConfig.Filters[filter]      ;以新UUID为Filters的UUID         
                    }
                    ChildID := TV_GetNext(ChildID)
                }
            }
            else if (QZImport_ObjTop[ItemID] = "vimd" )
            {
                ChildID := TV_GetChild(ItemID)
                Loop
                {
                    if not ChildID ; 没有更多项目了.
                        break
                    if TV_Get(ChildID, "Check")
                    {
                        AppVIMD:=QZImport_Objvimd[ChildID].name
                         Loop % gQZConfig.vimd.MaxIndex()
                        {
                            if (gQZConfig.vimd[A_index].name=AppVIMD)
                            {
                                QZImport_Objvimd[ChildID].name.="-副本"
                                ;重新修改关联函数的名称，防止重复
                                TemCode:=QZImport_Objvimd[ChildID].Code
                                TemCode:=StrReplace(TemCode,"_Init()","_Init1()")
                                TemCode:=StrReplace(TemCode,"_ChangeMode()","_ChangeMode1()")
                                TemCode:=StrReplace(TemCode,"_ActionBefore()","_ActionBefore1()")
                                TemCode:=StrReplace(TemCode,"_ActionAfter()","_ActionAfter1()")
                                TemCode:=StrReplace(TemCode,"_Show(aTemp, aMore)","_Show1(aTemp, aMore)")
                                QZImport_Objvimd[ChildID].Code:=TemCode
                                break
                            }
                        }                        
                        loop,%  QZImport_Objvimd[ChildID]["Modes"].MaxIndex()
                        {
                            ItemMode:= QZImport_Objvimd[ChildID]["Modes"][A_index]
                            ModeID:=A_index
                            ;~ msgbox % ItemMode["Maps"].MaxIndex()    ;可行
                            ;~ msgbox % ItemMode.Maps.MaxIndex()       ;可行
                            loop,% ItemMode["Maps"].MaxIndex()
                            {
                               ItemUUID :=ItemMode["Maps"][A_index].UUID
                                if (substr(ItemUUID,1,1)="<")       ;跳过内置命令
                                    continue
                                if (strlen(gQZImportConfig.Items[ItemUUID].NewID))
                                    ItemsUUID:=gQZImportConfig.Items[ItemUUID].NewID
                                else
                                    ItemsUUID:=UUIDCreate(1, "U")     ;生成新的ItemsUUID
                                ;~ msgbox % ItemsUUID
                                ;if (substr(ItemUUID,1,1)!="<")
                                gQZConfig.Items[ItemsUUID] := gQZImportConfig.Items[ItemUUID]       ;以新UUID为Items的UUID
                                QZImport_Objvimd[ChildID]["modes"][ModeID].maps[A_index].UUID:=ItemsUUID
                                gQZImportConfig.Items[ItemUUID].NewID:=ItemsUUID   ;标记新的UUID，防止二次生成
                                ;~ msgbox %  QZImport_Objvimd[ChildID]["modes"][ModeID].maps[A_index].UUID
                                ;~ msgbox %  QZImport_Objvimd[ChildID].modes[ModeID].maps[A_index].UUID
                            }
                        }
                        ;~ msgbox % gQZConfig.vimd.MaxIndex()
                        if gQZConfig.vimd.MaxIndex()
                            gQZConfig.vimd[gQZConfig.vimd.MaxIndex()+1] := QZImport_Objvimd[ChildID]
                        else 
                            gQZConfig.vimd[1] :=  QZImport_Objvimd[ChildID]  
                    }
                    ChildID := TV_GetNext(ChildID)
                }
            }
            else if (QZImport_ObjTop[ItemID] = "gesture" )
            {
                
            }
        }
        if not ItemID  ; 没有更多项目了.
            break
    }
    ;备份文件
    configfile:=QZGlobal.Config
    configbak=%A_ScriptDir%\user\Config备份(%A_YYYY%%A_MM%%A_DD%-%A_hour%%A_min%%A_sec%).json
    filecopy,%configfile%,%configbak%
    ;保存文件
    QZ_WriteConfig(QZ_GetConfig(), QZGlobal.Config)
    ;~ GUI_Rebuild()
    Send_WM_COPYData("Reload")
    If (aJson=0)
    {
        ; 复制文件
        FileCopyDir, %QZAFileTemp%, %A_ScriptDir%, 1
        ;~ msgbox % QZAFileTemp
        FileRemoveDir, %QZAFileTemp%, 1
        ;~ QZActionCheck()
        Send_WM_CopyData("Reload")
        Gui, QZImport: Destroy
        MsgBox, 32,, %QZAFile% 导入成功!
        ExitApp
    }

   msgbox,导入完成，请重启QZ
}

QZImport_UserENV(aID)
{
   global  gQZImportConfig,gQZConfig,QZImport_ObjMenuZ ;,QZImport_Objvimd,QZImport_Objgesture
    ObjArray := []
    ObjArray:=gQZConfig.setting.userenv
    Index := 1
    ChildID := TV_GetChild(aID)
    Loop
    {
        if not ChildID ; 没有更多项目了.
            break
        if TV_Get(ChildID, "Check")
        {
            if IsObject(QZImport_ObjSetting[ChildID])
            {
                ;~ ObjArray[Index] := IsObject(QZImport_ObjSetting[ChildID]) ? QZImport_ObjSetting[ChildID] : {}       ;导出菜单项对应
                EnvString:={}
                EnvString:=IsObject(QZImport_ObjSetting[ChildID]) ? QZImport_ObjSetting[ChildID] : {}       ;导出菜单项对应
                EnvName:=RegExReplace(EnvString["name"],"i)\s\|\|.*$","")
                EnvName:=trim(EnvName)
                EnvValue:=RegExReplace(EnvString["name"],"i)^.*\s\|\|\s*","")
                EnvValue:=trim(EnvValue)
                IsExist:=0
                for k,v in ObjArray
                {
                    if (k=EnvName)
                    {
                        IsExist:=1
                        break
                    }
                }
                if (IsExist=1)
                    continue
                if ObjArray.MaxIndex()
                    gQZConfig.setting.userenv[ObjArray.MaxIndex()+1] := {name:EnvName,value:EnvValue}
                else
                    gQZConfig.setting.userenv[1] := {name:EnvName,value:EnvValue}
            }
        }
        ChildID := TV_GetNext(ChildID)
        ;msgbox % QZImport_ObjMenuZ[ChildID].name "`n" ChildID
    }
}

QZImport_DoSub(aID,NewItemIsRed) ;,ObjArray)
{
    global  gQZImportConfig,QZImport_ObjMenuZ,gQZConfig ;,QZImport_Objvimd,QZImport_Objgesture
    ObjArray := []
    Index := 1
    ;~ ObjArray:=gQZConfig["menuz"] 
    ;~ msgbox % ObjArray.MaxIndex()
    ;~ if ObjArray.MaxIndex()
        ;~ Index := ObjArray.MaxIndex()+1
    ;~ else
        ;~ Index := 1
    ChildID := TV_GetChild(aID)
    Loop
    {
        if not ChildID ; 没有更多项目了.
            break
        if TV_Get(ChildID, "Check")
        {
            if IsObject(QZImport_ObjMenuZ[ChildID])
            {
                ObjArray[Index] := IsObject(QZImport_ObjMenuZ[ChildID]) ? QZImport_ObjMenuZ[ChildID] : {}       ;导出菜单项对应
                if NewItemIsRed
                    ObjArray[index].options.ColorBack:= "0xff0000"
                MenuzID:=UUIDCreate(1, "U")   ;生成新的MenuzID
                ObjArray[index].id:=MenuzID     ;以新UUID为menuz的id
                ;以下：导出菜单项对应的Item
                ItemUUID := QZImport_ObjMenuZ[ChildID].uuid
                ItemsUUID:=UUIDCreate(1, "U")     ;生成新的ItemsUUID
                gQZConfig.Items[ItemsUUID] := gQZImportConfig.Items[ItemUUID]       ;以新UUID为Items的UUID
                ObjArray[index].uuid:=ItemsUUID
                ;以下：; 导出菜单项对应的filter
                Filter:=[]                                                                          
                Filter:=QZImport_ObjMenuZ[ChildID].Filter
                loop,% Filter.MaxIndex()
                {
                    FilterID:=Filter[a_index]
                    if gQZImportConfig.Filters[FilterID] .NewID                             ;如果本筛选器在本次导入中已生成新的UUID，则使用标志的NewID，否则生成新的UUID
                        FilterUUID:=gQZImportConfig.Filters[FilterID] .NewID
                    else
                        FilterUUID:=UUIDCreate(1, "U")      ;生成新的FilterUUID
                    for k,v in gQZConfig.filters
                    {
                        if v.name=gQZImportConfig.Filters[FilterID].Name
                        {
                            gQZImportConfig.Filters[FilterID].name.= "-副本"
                            break
                        }
                    }
                    gQZConfig.Filters[FilterUUID]:=gQZImportConfig.Filters[FilterID]      ;以新UUID为Filters的UUID
                    ;~ gQZImportConfig.Filters.Delete(FilterID)        ;移除已经添加项，避免在后面导入筛选器时重复添加
                    gQZImportConfig.Filters[FilterID].NewID:=FilterUUID       ;标记已经添加项，避免在后面导入筛选器时重复添加
                    ObjArray[index].uuid.Filter[a_index]:=FilterUUID
                }
            }
            else if IsObject(QZImport_Objvimd[ChildID])
            {
                
            }
            else if IsObject(QZImport_Objgesture[ChildID])
            {
                
            }
            if TV_GetChild(ChildID)
                ObjArray[Index].SubItem := QZImport_DoSub(ChildID,NewItemIsRed)  ;,ObjArray)
            Index++
        }
        ChildID := TV_GetNext(ChildID)
        ;msgbox % QZImport_ObjMenuZ[ChildID].name "`n" ChildID
    }
    return ObjArray
}

;~ SetExplorerTheme(HCTL) 
;~ { ; HCTL : handle of a ListView or TreeView control
   ;~ If (DllCall("GetVersion", "UChar") > 5) {
      ;~ VarSetCapacity(ClassName, 1024, 0)
      ;~ If DllCall("GetClassName", "Ptr", HCTL, "Str", ClassName, "Int", 512, "Int")
         ;~ If (ClassName = "SysListView32") || (ClassName = "SysTreeView32")
            ;~ Return !DllCall("UxTheme.dll\SetWindowTheme", "Ptr", HCTL, "WStr", "Explorer", "Ptr", 0)
   ;~ }
   ;~ Return False
;~ }

; =============================================
; 加载导出界面
; =============================================
QZExport:

cons_Setting := "【设置】"
cons_SettingIcon := "%A_ScriptDir%\Icons\default.icl:25"
cons_Filters := "【过滤器】"
cons_FiltersIcon := "%windir%\system32\shell32.dll:54"
cons_menuz := "【菜单项目】"
cons_menuzIcon := "%windir%\system32\shell32.dll:43"
cons_vimd := "【VIMD】"
cons_vimdIcon := "%windir%\system32\shell32.dll:1"
cons_gesture := "【鼠标手势】"
cons_gestureIcon := "%windir%\system32\shell32.dll:54"
cons_Separator := "--------------"


cons_HelpExport =
(
欢迎使用 QuickZ 导出功能！

一、关于QZA（QuickZ App）
      QuickZ App 是为了相互分享优秀的小程序、小脚本和高效率用法。作为QuickZ中的插件，其本质是一个“ZIP”文件，但是后缀名改成了 QZA 而已。QuickZ会专门进行处理和导入。

二、导出功能为3步：
1、设置要导出的菜单项，【默认自动导出相对应的文件筛选器】。
2、设置要导出的文件。（分享程序、图标、脚本等）
3、给导出的QZA设定个好名字，还有分享的作者、详细的说明。如菜单对哪些文件类型有效等。越详细,帮助越大。

三、导出的内容
      除了导出为 *.qza 文件之外。为了方便共享，还支持导出为Json格式。但是Json格式有个比较明显的限制：不能带文件！Json格式非常适合在QQ群或者邮件或者网页上共享。点击导出为Json格式后，会保存为 *.json 文件，并且把内容复制到剪切板中，方便即时分享。

说明到此结束。Enjoy It ！ by Array
)
;3、设置菜单项配置涉及用户变量

global QZExport_ObjSetting := {}       ;设置 数组
global QZExport_ObjTop := {}           ;窗体树 数组
global QZExport_ObjFilters := {}            ;过滤器 数组
global QZExport_ObjMenuZ := {}         ;菜单项 数组
global QZExport_Objvimd := {}          ;vimd 数组
global QZExport_Objgesture:={}         ;gesture 数组
global QZExport_ObjFile:={}            ;文件 数组
;~ QZExport_ObjUserVar := {}       ;JOSN MenuZ

if QZExport_ImgItem
    IL_Destroy(QZExport_ImgItem)
else
    QZExport_ImgItem := IL_Create(1,10,0)

if QZExport_ImgFile
    IL_Destroy(QZExport_ImgFile)
else
    QZExport_ImgFile := IL_Create(1,10,0)

QZExport_ImgItem_Icons := {}
QZExport_ImgFile_Icons := {}

GetExtIcon("Folder", iFile, iNum)
IL_Add(QZExport_ImgFile, ifile, iNum)

Gui, QZExport: Destroy
Gui, QZExport: Default
Gui, QZExport: +theme -DPIScale +hwndhQZExport
Gui, QZExport: Font, s9, Microsoft YaHei
GUI, QZExport: Add, Tab2, x5 y5 w400 h500 ,说明|菜单|文件|导出
GUI, QZExport: Add, Edit, x15 y40 w380 h455 Readonly, % cons_HelpExport
GUI, QZExport: Tab, 2
Gui, QZExport: Add, TreeView, Checked x15 y40 w380 h455 +hwndhQZExportItem AltSubmit ImageList%QZExport_ImgItem% -Lines 0x1000 gQZExport_TVEvent_Item
GUI, QZExport: Tab, 3
Gui, QZExport: Add, TreeView, Checked x15 y40 w380 h410 +hwndhQZExportFile AltSubmit ImageList%QZExport_ImgFile% gQZExport_TVEvent_File
GUI, QZExport: Add, Button, x275 y460 w120 gQZExport_Files_Add, 添加文件夹(&A)
GUI, QZExport: Tab, 4
;GUI, QZExport: Add, ListView, x15 y40 w380 h455 Grid, 变量名|内容
;GUI, QZExport: Tab, 5
GUI, QZExport: Add, Edit, x15 y40 w380, QZA:名称
GUI, QZExport: Add, Edit, x15 y75 w380, QZA:作者
GUI, QZExport: Add, Edit, x15 y110 w380 h340, QZA:说明/版本/相关信息
GUI, QZExport: Add, Button, x65 y460 w120 gQZExport_Json, 导出QZA://(&A)
GUI, QZExport: Add, Button, x195 y460 w120 gQZExport_QZA,  导出QZA文件(&S)
GUI, QZExport: Add, Button, x325 y460 w70 gQZExportGUIClose, 关闭(&C)
SetExplorerTheme(hQZExportItem)
SetExplorerTheme(hQZExportFile)
Gui, QZExport: Show, w410 h510, QZA 导出
ControlSend, Edit1, {end}, ahk_id %hQZExport%
Gui, QZExport: TreeView, SysTreeView321
QZExport_LoadSetting()
QZExport_LoadMenuZ(cons_menuz, cons_menuzIcon, "menuz")
QZExport_LoadFilters()
QZExport_LoadVIMD(cons_vimd, cons_vimdIcon, "vimd")
;~ QZExport_Load(cons_gesture, cons_gestureIcon, "gesture")
Gui, QZExport: TreeView, SysTreeView322
QZExport_Files(A_ScriptDir "\Apps")
QZExport_Files(A_ScriptDir "\Docs")
QZExport_Files(A_ScriptDir "\Lib")
QZExport_Files(A_ScriptDir "\User")
return

QZExportGUIClose:
    ExitApp
return

QZExport_QZA:
  QZExport_Do()
return

QZExport_Json:
  if Strlen(qzaString := QZExport_Do(True))
  {
      GuiControlGet, QZA_Name,   , Edit2
      GuiControlGet, QZA_Author, ,Edit3
      GuiControlGet, QZA_Info,   , Edit4
      Clipboard := qzaString "`n`n!以下为说明，无需复制`n====================================`nQZA名称:" QZA_Name "`nQZA作者:" QZA_Author "`nQZA说明:"  QZA_Info "`n===================================="
  }
return

QZExport_TVEvent_Item:
    Gui, QZExport: default
    Gui, QZExport: TreeView, SysTreeView321
    If A_GuiEvent = Normal
        GoSub, QZExport_TVEvent
return

QZExport_TVEvent_File:
    Gui, QZExport: default
    Gui, QZExport: TreeView, SysTreeView322
    If A_GuiEvent = Normal
        GoSub, QZExport_TVEvent
return


QZExport_TVEvent:
    TV_Modify(A_EventInfo, "select")
    if TV_Get(A_EventInfo, "Check")
    {
        QZExport_CheckSetting(A_EventInfo, "check")
        QZExport_CheckParent(A_EventInfo, "Check")
        QZExport_CheckChild(A_EventInfo, "Check")
    }
    else
    {
        QZExport_CheckSetting(A_EventInfo, "-check")
        QZExport_CheckChild(A_EventInfo, "-Check")
    }
return
; 加载父项
QZExport_CheckParent(aID, opt)
{
    global QZExport_ObjMenuZ, QZExport_ObjFilters
    if (Parentid := TV_GetParent(aID))
    {
        TV_Modify(ParentID, opt)
        QZExport_CheckParent(ParentID, opt)
        QZExport_CheckSetting(ParentID, opt)
    }
}
; 加载子项
QZExport_CheckChild(aID, opt)
{
    global QZExport_ObjMenuZ, QZExport_ObjFilters
    if ( ChildID := TV_GetChild(aID) )
    {
        Loop
        {
            if ChildID
            {
                if ( SubChildID := TV_GetChild(ChildID) )
                    QZExport_CheckChild(ChildID, opt)
                TV_Modify(ChildID, opt)
                QZExport_CheckSetting(ChildID, opt)
            }
            else
            {
                break
            }
            ChildID := TV_GetNext(ChildID)
        }
    }
}

QZExport_LoadSetting()      ;加载 Json下的setting
{
    global cons_Setting, cons_SettingIcon, QZExport_ObjTop, QZExport_ObjSetting, gQZConfig
    opt := QZExport_TVOptions({icon:cons_SettingIcon})
    ParentID := TV_Add(cons_Setting, 0, "Expand " opt)
    QZExport_ObjTop[ParentID] := "setting"
    ;~ for name, var in gQZConfig.setting
        ;~ QZExport_ObjSetting[TV_Add(name, ParentID, opt)] := {name:name, option:true} 
    for name, var in gQZConfig.setting
    {
        if (name!="userenv")
            QZExport_ObjSetting[TV_Add(name, ParentID, opt)] := {name:name, option:true}  
        else
        {
            UserPID:=TV_Add("userenv", ParentID, opt)
            QZExport_ObjSetting[UserPID] :=  {name:"userenv", option:true}  
            UserEnvArray:=gQZConfig.setting.userenv
            Loop % UserEnvArray.MaxIndex()
            {
                ItemEnv:=UserEnvArray[A_Index]
                EnvName:=itemenv.name . "   ||   " .  itemenv.value
                QZExport_ObjSetting[TV_Add(EnvName, UserPID, opt)] := {name:EnvName,value:""} 
            }
        }
    }
}

QZExport_LoadFilters()  ;加载 Json下的filter
{
    global cons_Filters, cons_FiltersIcon, QZExport_ObjTop, QZExport_ObjFilters, gQZConfig
    opt := QZExport_TVOptions({icon:cons_FiltersIcon})
    ParentID:= TV_Add(cons_Filters, 0, "Expand " opt)
    QZExport_ObjTop[ParentID] := "Filters"
    for name, var in gQZConfig.Filters
    {
        ShowName:=var.name
        QZExport_ObjFilters[TV_Add(ShowName, ParentID, opt)] := {name:name, option:false}
    }
}

QZExport_LoadMenuZ(aName, aICON, aObjName)   ;加载 Json下的menuz
{
    global QZExport_ObjTop, gQZConfig
    aObj := gQZConfig[aObjName]
    opt := QZExport_TVOptions({icon:aICON})
    SubID := TV_Add(aName, 0, opt " expand")
    QZExport_ObjTop[SubID] := aObjName
    QZExport_LoadMenuZSub(aObj, SubID,aLevel:=2)
}

QZExport_LoadMenuZSub(aObjSub, aID,aLevel)       ;加载 Json下的menuz的子项
{
    global  cons_Separator,  QZExport_ObjMenuZ,gQZConfig
    Loop % aObjSub.MaxIndex()
    {
        Item := aObjSub[A_Index]
        ItemUUID:=Item.uuid
        name := Item.name
        Showname := gQZConfig.Items[ItemUUID].name
        opt := QZExport_TVOptions(item.options)
        if not strlen(item.uuid) ;and aLevel > 2
            TV_Add(cons_Separator, aID, opt)
        else
        {
           SubID := TV_Add(Showname, aID, opt)
            QZExport_ObjMenuZ[SubID] := Item
        }
        if IsObject(Item.SubItem)
          QZExport_LoadMenuZSub(Item.SubItem, SubID,aLevel+1)
    }
}

QZExport_LoadVIMD(aName, aICON, aObjName)   ;加载 Json下的VIMD
{
    global QZExport_ObjTop, gQZConfig
    aObj := gQZConfig[aObjName]
    opt := QZExport_TVOptions({icon:aICON})
    SubID := TV_Add(aName, 0, opt " expand")
    QZExport_ObjTop[SubID] := aObjName
    QZExport_LoadVIMDSub(aObj, SubID,aLevel:=2)
}

QZExport_LoadVIMDSub(aObjSub, aID,aLevel)       ;加载 Json下的VIMD的子项
{
    global  QZExport_Objvimd,gQZConfig
    Loop % aObjSub.MaxIndex()
    {
        Item := aObjSub[A_Index]
        name := Item.name
        ;~ opt := QZExport_TVOptions(item.options)
        ParentID := TV_Add(name, aID)
        QZExport_Objvimd[ParentID] := Item
        ;~ loop % Item.Modes.maxindex()
        ;~ {
            ;~ Mode:=Item.Modes[A_index]
            ;~ ModeName:=mode.Name            
            ;~ SubID := TV_Add(ModeName, ParentID)
        ;~ }
    }
}

QZExport_TVOptions(aIcon)       ;返回菜单项对应的图标
{
    global QZExport_ImgItem, QZExport_ImgItem_Icons
    Opt := "" ;默认返回的TV控件的选项为空
    ; == 开始判断 TreeView 的图标选项 ==========
    ;~ icon := aIcon.iconfile
    icon := aIcon.iconfile      ;Kawvin修改
    if strlen(icon) ; icon 有效
    {
        if ic := QZExport_ImgItem_Icons[icon] ; 如果保存对象的QZExport_ImgItem_Icons中有对应的列表，则直接设置，无需判断
            opt_icon := "icon" ic
        else if RegExMatch(icon, ":[-\d]*$") ; example.exe:1 的格式
        {
            pos := RegExMatch(icon, ":[^:]*$")
		    file   := QZ_ReplaceEnv(SubStr(icon, 1, pos-1))
            Number := (number := substr(icon, pos+1)) > 0 ? Number + 1 : Number
            ic := IL_Add(QZExport_ImgItem, file, Number)
            if ic
            {
                Opt_icon := "icon" ic 
                QZExport_ImgItem_Icons[icon] := ic ; 保存到 QZExport_ImgItem_Icons 中，避免重复加载
            }
      }
	  else
      {
            file := QZ_ReplaceEnv(icon)   ; menuz.ico 的格式
            ic := IL_Add(QZExport_ImgItem, file)
            if ic
            {
                Opt_icon := "icon" ic 
                QZExport_ImgItem_Icons[icon] := ic ; 保存到 QZExport_ImgItem_Icons 中，避免重复加载
            }
      }
    }
    else
        opt_icon := "icon9999" 
    if not ic ; 如果无icon，必须设置为最大值，让图标为空
        opt_icon := "icon9999" 
    return opt_icon
    ; == 结束判断 TreeView 的图标选项 ==========
}

QZExport_Files_Add:         ;添加文件夹按键
    FileSelectFolder, NewFolder, %A_ScriptDir%, 0, 请选择文件夹
    if (NewFolder="")
        return
    QZExport_Files(NewFolder)
return

QZExport_Files(aPath, aID=0)        ;加载导出文件
{
    Gui, QZExport: TreeView, SysTreeView322
    global QZExport_ObjFile
    SplitPath, aPath, filename
    ParentID := TV_Add(filename, aID, "icon" QZEX_GetIcon(aPath))
    QZExport_ObjFile[ParentID] := aPath
    Loop, %aPath%\*.*, 1
    {
        SplitPath, A_loopfilename, , , ext
        If (FileExist(A_loopfilefullpath), "D")
        {
            QZExport_Files(A_loopfilefullpath, ParentID)
        }
        else
        {
            PathID := TV_Add(A_loopfilename, ParentID, "icon" QZEX_GetIcon(A_loopfilename))
            QZExport_ObjFile[PathID] := A_loopfilefullpath
        }
    }
}

QZEX_GetIcon(aPath)     ;获取导出文件对应图标
{
    global QZExport_ImgFile, QZExport_ImgFile_Icons
    if Instr(Fileexist(aPath),"D")
        return 1
    SplitPath, aPath, , , ext
    if QZExport_ImgFile_Icons[ext]
    {
        idx := QZExport_ImgFile_Icon[ext]
    }
    else
    {
        GetExtIcon("." ext, iFile, iNum)
        if instr(inum, "-")
            idx := IL_Add(QZExport_ImgFile, ifile, inum)
        else
            idx := IL_Add(QZExport_ImgFile, ifile, inum+1)
        QZExport_ImgFile_Icon[ext] := idx
    }
    return idx
}

QZExport_CheckSetting(aID, aOpt)
{
    global QZExport_ObjSetting, QZExport_ObjTop
    if (QZExport_ObjTop[TV_GetParent(aID)] = "setting")
    {
        if InStr(aOpt, "-")
            QZExport_ObjSetting[aID].option := False
        else
            QZExport_ObjSetting[aID].option := True
    }
}

QZExport_Do(aJson=false)
{
    global QZExport_ObjMenuZ, QZExport_ObjFilters, QZExport_ObjTop, QZExport_ObjFile, QZExport_ObjSetting, QZExport_Objvimd,gQZConfig    ;,QZExport_ObjUserVar
    QZA_Json := Json.Parse("{}")
    Gui, QZExport: Default
    GuiControlGet, QZA_Name,   , Edit2
    GuiControlGet, QZA_Author, ,Edit3
    GuiControlGet, QZA_Info,   , Edit4
    QZA_Json["QuickzApp"] := {Name:QZA_Name, Author:QZA_Author, Info:QZA_Info}
    Gui, QZExport: TreeView, SysTreeView321
    iTop := ""
    ;iFilter := ""
    iFilterIndex := 0
    iMenu := ""
    iMenuIndex := 0
    QZA_Json["items"] := {}
    ItemID = 0  ; 这样使得首次循环从树的顶部开始搜索.
    Loop
    {
        ItemID := TV_GetNext(ItemID)
        if TV_Get(ItemID, "Check")
        {
            if (QZExport_ObjTop[ItemID] = "setting" )
            {
                QZA_Json["setting"] := {}
                ChildID := TV_GetChild(ItemID)
                Loop
                {
                    if not ChildID ; 没有更多项目了.
                        break
                    if TV_Get(ChildID, "Check")
                    {
                        set := QZExport_ObjSetting[ChildID].name
                        if (set="gesture") or (set="global") or (set="menuz") or (set="vimd")
                        {
                            set := QZExport_ObjSetting[ChildID].name
                            QZA_Json["setting"][set] := gQZConfig.Setting[set]
                        } else if  (set="userenv") {
                            QZA_Json["setting"]["userenv"] := QZExport_UserENV(ChildID)
                        } else {
                        }
                    }
                    ChildID := TV_GetNext(ChildID)
                }
            }
            else if (QZExport_ObjTop[ItemID] = "Filters" )
            {
                QZA_Json["Filters"] := {}
                ChildID := TV_GetChild(ItemID)
                Loop
                {
                    if not ChildID ; 没有更多项目了.
                        break
                    if TV_Get(ChildID, "Check")
                    {
                        filter := QZExport_ObjFilters[ChildID].name
                        QZA_Json["Filters"][filter] := gQZConfig.Filters[filter]
                    }
                    ChildID := TV_GetNext(ChildID)
                }
            }
            else if (QZExport_ObjTop[ItemID] = "menuz" )
            {
                QZA_Json["menuz"] := {}
                ;~ QZA_Json[QZExport_ObjTop[ItemID]] := QZExport_DoSub(ItemID)
                ItemArray := []
                if not IsObject(QZA_Json["Filters"] )
                ;~ if (QZA_Json["Filters"].Length() )=0
                    QZA_Json["Filters"] := {}
                QZA_Json["menuz"] := QZExport_DoSub(ItemID,ItemArray,QZA_Json["Filters"])
                QZA_Json["items"] := ItemArray
            }
            else if (QZExport_ObjTop[ItemID] = "vimd" )
            {
                QZA_Json["vimd"] := {}
                ChildID := TV_GetChild(ItemID)
                Loop
                {
                    if not ChildID ; 没有更多项目了.
                        break
                    if TV_Get(ChildID, "Check")
                    {
                        if QZA_Json["vimd"] .MaxIndex()
                            QZA_Json["vimd"] [QZA_Json["vimd"] .MaxIndex()+1] := QZExport_Objvimd[ChildID]
                        else
                           QZA_Json["vimd"][1] := QZExport_Objvimd[ChildID]
                        loop,% QZExport_Objvimd[ChildID]["Modes"].MaxIndex()
                        {
                            ItemMode:=QZExport_Objvimd[ChildID]["Modes"][A_index]
                            ;~ msgbox % ItemMode["Maps"].MaxIndex()    ;可行
                            ;~ msgbox % ItemMode.Maps.MaxIndex()       ;可行
                            loop,% ItemMode["Maps"].MaxIndex()
                            {
                                ItemUUID:=ItemMode["Maps"][A_index].UUID
                                ;~ if (substr(ItemUUID,1,1)="<")       ;跳过内置命令
                                    ;~ continue
                                QZA_Json["Items"][ItemUUID] := gQZConfig.Items[ItemUUID]
                            }
                        }                       
                    }
                    ChildID := TV_GetNext(ChildID)
                }
            }
            else if (QZExport_ObjTop[ItemID] = "gesture" )
            {
                
            }
        }
        if not ItemID  ; 没有更多项目了.
            break
    }

    Jsontext := Json.stringify(QZA_Json, 2)
    TempDir := A_Temp "\QuickZ_QZA\"
    TempJson := TempDir "qza.json"
    PathTopack := TempDir "*.*"
    PathZip := A_Temp "\QuickzApp.zip"

    If Fileexist(TempDir)
        FileRemoveDir, %TempDir%, 1
    FileCreateDir, %TempDir%
    FileAppend, %Jsontext% , %TempJson%

    If aJson
    {
        FileSelectFile, OutputVar ,S17, *RootDir\Share,请选择保存JSON文件的目录,JSON文件(*.json)
        if ErrorLevel
            return
        if (substr(OutputVar,-4)!=".json")
            OutputVar.=".json"
        IfExist,%OutputVar%
            FileDelete,%OutputVar%
        if (OutputVar!=".json")
            FileAppend, %Jsontext% , %OutputVar%
        Msgbox, 32, %cons_Title_QZA% , 导出JSON完成，QZA://文本已经复制到剪切板!
        return "QZA://" Json.stringify(QZA_Json)
        /*
        FileSelectFile, PathJson, S17, %A_ScriptDir%, 保存QZA Json, *.Json
        if strlen(PathJson)
        {
            if not RegExMatch(PathJson, "i)\.json$")
                PathJson .= ".json"
            FileMove, %TempJson%, %PathJson%, 1
            return "QZA://" Json.stringify(QZA_Json)
        }
        return
        */
    }

    Gui, QZExport: TreeView, SysTreeView322
    ItemID = 0  ; 这样使得首次循环从树的顶部开始搜索.
    Loop
    {
        ItemID := TV_GetNext(ItemID, "Checked")  ; 把 "Full" 替换为 "Checked" 来找出所有含复选标记的项目.
        if not ItemID  ; 没有更多项目了.
            break
        Pathfull := QZExport_ObjFile[ItemID]
        ;~ msgbox % ItemID "--" Pathfull
        StringReplace, PathRelative, Pathfull, %A_ScriptDir%
        PathNew := TempDir . PathRelative
        If InStr(Fileexist(Pathfull), "D")
            FileCreateDir, %PathNew%
        else
            FileCopy, %Pathfull%, %PathNew%
    }
    if Fileexist(PathZip)
        FileDelete, %PathZip%
    ObjZip := Zipfile(PathZip)
    ObjZip.pack(PathTopack)
    FileSelectFile, PathQZA, S17, %A_ScriptDir%, 保存QZA, *.qza
    if ErrorLevel
        return
    if strlen(PathQZA)
    {
        if not RegExMatch(PathQZA, "i)\.qza$")
            PathQZA .= ".qza"
        FileMove, %PathZip%, %PathQZA%, 1
    }
    MsgBox,导出QZA完成
}

QZExport_UserENV(aID)
{
   global  gQZConfig,QZExport_ObjMenuZ ;,QZExport_Objvimd,QZExport_Objgesture
    ObjArray := []
    Index := 1
    ChildID := TV_GetChild(aID)
    Loop
    {
        if not ChildID ; 没有更多项目了.
            break
        if TV_Get(ChildID, "Check")
        {
            if IsObject(QZExport_ObjSetting[ChildID])
            {
                ;~ ObjArray[Index] := IsObject(QZExport_ObjSetting[ChildID]) ? QZExport_ObjSetting[ChildID] : {}       ;导出菜单项对应
                EnvString:={}
                EnvString:=IsObject(QZExport_ObjSetting[ChildID]) ? QZExport_ObjSetting[ChildID] : {}       ;导出菜单项对应
                EnvName:=RegExReplace(EnvString["name"],"i)\s\|\|.*$","")
                EnvName:=trim(EnvName)
                EnvValue:=RegExReplace(EnvString["name"],"i)^.*\s\|\|\s*","")
                EnvValue:=trim(EnvValue)
                ;~ msgbox % EnvName "--" EnvValue
                if ObjArray.MaxIndex()
                    ObjArray[ObjArray.MaxIndex()+1] := {name:EnvName,value:EnvValue}
                else
                    ObjArray[1] := {name:EnvName,value:EnvValue}
            }
        }
        ChildID := TV_GetNext(ChildID)
        ;msgbox % QZExport_ObjMenuZ[ChildID].name "`n" ChildID
    }
    return ObjArray
}

QZExport_DoSub(aID,byref tArray,byref fArray)
{
    global  gQZConfig,QZExport_ObjMenuZ ;,QZExport_Objvimd,QZExport_Objgesture
    ObjArray := []
    Index := 1
    ChildID := TV_GetChild(aID)
    Loop
    {
        if not ChildID ; 没有更多项目了.
            break
        if TV_Get(ChildID, "Check")
        {
            if IsObject(QZExport_ObjMenuZ[ChildID])
            {
                ObjArray[Index] := IsObject(QZExport_ObjMenuZ[ChildID]) ? QZExport_ObjMenuZ[ChildID] : {}       ;导出菜单项对应
                ;以下：导出菜单项对应的Item
                ItemUUID := QZExport_ObjMenuZ[ChildID].uuid        
                tArray[ItemUUID] := gQZConfig.Items[ItemUUID]
                ;~ tArray.push(gQZConfig.Items[ItemUUID])
                ;以下：; 导出菜单项对应的filter
                Filter:=[]                                                                          
                Filter:=QZExport_ObjMenuZ[ChildID].Filter
                loop,% Filter.MaxIndex()
                {
                    FilterID:=Filter[a_index]
                    fArray[FilterID]:=gQZConfig.Filters[FilterID]
                }
            }
            else if IsObject(QZExport_Objvimd[ChildID])
            {
                
            }
            else if IsObject(QZExport_Objgesture[ChildID])
            {
                
            }
            if TV_GetChild(ChildID)
                ObjArray[Index].SubItem := QZExport_DoSub(ChildID,tArray,fArray)
            Index++
        }
        ChildID := TV_GetNext(ChildID)
        ;msgbox % QZExport_ObjMenuZ[ChildID].name "`n" ChildID
    }
    return ObjArray
}

SetExplorerTheme(HCTL) 
{ ; HCTL : handle of a ListView or TreeView control
   If (DllCall("GetVersion", "UChar") > 5) {
      VarSetCapacity(ClassName, 1024, 0)
      If DllCall("GetClassName", "Ptr", HCTL, "Str", ClassName, "Int", 512, "Int")
         If (ClassName = "SysListView32") || (ClassName = "SysTreeView32")
            Return !DllCall("UxTheme.dll\SetWindowTheme", "Ptr", HCTL, "WStr", "Explorer", "Ptr", 0)
   }
   Return False
}